home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / mpeg_play-2.1 / ordered2.c < prev    next >
C/C++ Source or Header  |  1995-05-09  |  8KB  |  338 lines

  1. /*
  2.  * ordered2.c --
  3.  *
  4.  *      This file contains C code to implement a faster ordered dither
  5.  *      than the one found in ordered.c.  This dither is the default
  6.  *      if no dither is specified.
  7.  *
  8.  */
  9.  
  10. /*  
  11.  * Copyright (c) 1995 The Regents of the University of California.
  12.  * All rights reserved.
  13.  * 
  14.  * Permission to use, copy, modify, and distribute this software and its
  15.  * documentation for any purpose, without fee, and without written agreement is
  16.  * hereby granted, provided that the above copyright notice and the following
  17.  * two paragraphs appear in all copies of this software.
  18.  * 
  19.  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
  20.  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
  21.  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
  22.  * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  23.  * 
  24.  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
  25.  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  26.  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
  27.  * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
  28.  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  29.  */
  30.  
  31. #include "video.h"
  32. #include "proto.h"
  33. #include "dither.h"
  34.  
  35. #define DITH_SIZE 16
  36.  
  37.  
  38. /* Structures used to implement hybrid ordered dither/floyd-steinberg
  39.    dither algorithm.
  40. */
  41.  
  42. static unsigned char ***ditherPtr[DITH_SIZE];
  43.  
  44.  
  45. /*
  46.  *--------------------------------------------------------------
  47.  *
  48.  *  InitOrderedDither--
  49.  *
  50.  *    Structures intialized for ordered dithering. 
  51.  *
  52.  * Results:
  53.  *    None.
  54.  *
  55.  * Side effects:
  56.  *      None.
  57.  *
  58.  *--------------------------------------------------------------
  59.  */
  60.  
  61. void
  62. InitOrdered2Dither()
  63. {
  64.   unsigned char ****pos_2_cb;
  65.   unsigned char ***cb_2_cr;
  66.   unsigned char **cr_2_l;
  67.   int cb_val, cb_rval, cr_val, cr_rval, l_val, l_rval;
  68.   int i, j, pos;
  69.   int err_range, threshval;
  70.  
  71.   pos_2_cb = (unsigned char ****) malloc (DITH_SIZE*sizeof(unsigned char ***));
  72.   cb_2_cr = (unsigned char ***) malloc(CB_RANGE*sizeof(unsigned char **));
  73.   cr_2_l = (unsigned char **) malloc(CR_RANGE*sizeof(unsigned char *));
  74.  
  75.   for (pos=0; pos<DITH_SIZE; pos++) {
  76.     
  77.     pos_2_cb[pos] = (unsigned char ***) malloc(256*(sizeof(unsigned char **)));
  78.  
  79.     for (j=0; j<CB_RANGE; j++) {
  80.       cb_2_cr[j] = (unsigned char **) malloc(256*(sizeof(unsigned char *)));
  81.     }
  82.  
  83.     for (cb_val=0; cb_val<cb_values[0]; cb_val++) {
  84.       (pos_2_cb[pos])[cb_val] = cb_2_cr[0];
  85.     }
  86.  
  87.     for (cb_rval=0; cb_rval<(CB_RANGE-1); cb_rval++) {
  88.       err_range = cb_values[cb_rval+1] - cb_values[cb_rval];
  89.       threshval = ((pos*err_range)/DITH_SIZE)+cb_values[cb_rval];
  90.  
  91.       for (cb_val=cb_values[cb_rval]; cb_val<cb_values[cb_rval+1]; cb_val++) {
  92.     if (cb_val>threshval) (pos_2_cb[pos])[cb_val] = cb_2_cr[cb_rval+1];
  93.     else (pos_2_cb[pos])[cb_val] = cb_2_cr[cb_rval];
  94.       }
  95.     }
  96.  
  97.     for (cb_val=cb_values[CB_RANGE-1]; cb_val<256; cb_val++) {
  98.       (pos_2_cb[pos])[cb_val] = cb_2_cr[CB_RANGE-1];
  99.     }
  100.  
  101.     for (cb_rval=0; cb_rval<CB_RANGE; cb_rval++) {
  102.       
  103.       for (j=0; j<CR_RANGE; j++) {
  104.     cr_2_l[j] = (unsigned char *) malloc(256*(sizeof(unsigned char)));
  105.       }
  106.  
  107.       for (cr_val=0; cr_val < cr_values[0]; cr_val++) {
  108.     (cb_2_cr[cb_rval])[cr_val] = cr_2_l[0];
  109.       }
  110.  
  111.       for (cr_rval=0; cr_rval<(CR_RANGE-1); cr_rval++) {
  112.     err_range = cr_values[cr_rval+1] - cr_values[cr_rval];
  113.     threshval = ((pos*err_range)/DITH_SIZE)+cr_values[cr_rval];
  114.     
  115.     for (cr_val=cr_values[cr_rval]; cr_val<cr_values[cr_rval+1]; cr_val++) {
  116.       if (cr_val>threshval) (cb_2_cr[cb_rval])[cr_val] = cr_2_l[cr_rval+1];
  117.       else (cb_2_cr[cb_rval])[cr_val] = cr_2_l[cr_rval];
  118.     }
  119.       }
  120.       
  121.       for (cr_val=cr_values[CR_RANGE-1]; cr_val<256; cr_val++) {
  122.     (cb_2_cr[cb_rval])[cr_val] = cr_2_l[CR_RANGE-1];
  123.       }
  124.       
  125.       for (cr_rval=0; cr_rval<CR_RANGE; cr_rval++) {
  126.     
  127.     for (l_val = 0; l_val < lum_values[0]; l_val++) {
  128.       (cr_2_l[cr_rval])[l_val] = pixel[cb_rval+(cr_rval*CB_RANGE)+
  129.                         (0*CR_RANGE*CB_RANGE)];
  130.     }
  131.  
  132.     for (l_rval=0; l_rval<(LUM_RANGE-1); l_rval++) {
  133.       err_range = lum_values[l_rval+1] - lum_values[l_rval];
  134.       threshval = ((pos*err_range) /DITH_SIZE) + lum_values[l_rval];
  135.  
  136.       for (l_val = lum_values[l_rval]; l_val < lum_values[l_rval+1]; l_val++) {
  137.         if (l_val>threshval) (cr_2_l[cr_rval])[l_val] = 
  138.           pixel[cb_rval+(cr_rval*CB_RANGE)+((l_rval+1)*CR_RANGE*CB_RANGE)];
  139.         else (cr_2_l[cr_rval])[l_val] =
  140.           pixel[cb_rval+(cr_rval*CB_RANGE)+(l_rval*CR_RANGE*CB_RANGE)];
  141.       }
  142.     }
  143.  
  144.     for (l_val = lum_values[LUM_RANGE-1]; l_val < 256; l_val++) {
  145.       (cr_2_l[cr_rval])[l_val] = 
  146.         pixel[cb_rval+(cr_rval*CB_RANGE)+((LUM_RANGE-1)*CR_RANGE*CB_RANGE)];
  147.     }
  148.       }
  149.     }
  150.   }
  151.  
  152.   for (i=0; i<DITH_SIZE; i++) {
  153.     ditherPtr[i] = pos_2_cb[i];
  154.   }
  155. }
  156.  
  157.  
  158. /*
  159.  *--------------------------------------------------------------
  160.  *
  161.  * Ordered2DitherImage --
  162.  *
  163.  *    Dithers an image using an ordered dither.
  164.  *    Assumptions made:
  165.  *      1) The color space is allocated y:cr:cb = 8:4:4
  166.  *      2) The spatial resolution of y:cr:cb is 4:1:1
  167.  *      The channels are dithered based on the standard
  168.  *      ordered dither pattern for a 4x4 area. 
  169.  *
  170.  * Results:
  171.  *    None.
  172.  *
  173.  * Side effects:
  174.  *    None.
  175.  *
  176.  *--------------------------------------------------------------
  177.  */
  178. void
  179. Ordered2DitherImage (lum, cr, cb, out, h, w)
  180.     unsigned char *lum;
  181.     unsigned char *cr;
  182.     unsigned char *cb;
  183.     unsigned char *out;
  184.     int w, h;
  185. {
  186.   unsigned char *l, *r, *b, *o1, *o2;
  187.   unsigned char *l2;
  188.   unsigned char L, R, B;
  189.   int i, j;
  190.   unsigned char ***dp0 = ditherPtr[0];
  191.   unsigned char ***dp2 = ditherPtr[2];
  192.   unsigned char ***dp4 = ditherPtr[4];
  193.   unsigned char ***dp6 = ditherPtr[6];
  194.   unsigned char ***dp8 = ditherPtr[8];
  195.   unsigned char ***dp10 = ditherPtr[10];
  196.   unsigned char ***dp12 = ditherPtr[12];
  197.   unsigned char ***dp14 = ditherPtr[14];
  198.   unsigned char ***dp1 = ditherPtr[1];
  199.   unsigned char ***dp3 = ditherPtr[3];
  200.   unsigned char ***dp5 = ditherPtr[5];
  201.   unsigned char ***dp7 = ditherPtr[7];
  202.   unsigned char ***dp9 = ditherPtr[9];
  203.   unsigned char ***dp11 = ditherPtr[11];
  204.   unsigned char ***dp13 = ditherPtr[13];
  205.   unsigned char ***dp15 = ditherPtr[15];
  206.  
  207.   l = lum;
  208.   l2 = lum+w;
  209.   r = cr;
  210.   b = cb;
  211.   o1 = out;
  212.   o2 = out+w;
  213.  
  214.   for (i=0; i<h; i+=4) {
  215.  
  216.     for (j=0; j<w; j+=8) {
  217.  
  218.       R = r[0]; B = b[0];
  219.  
  220.       L = l[0];
  221.       o1[0] = ((dp0[B])[R])[L];
  222.       L = l[1];
  223.       o1[1] = ((dp8[B])[R])[L];
  224.       L = l2[0];
  225.       o2[0] = ((dp12[B])[R])[L];
  226.       L = l2[1];
  227.       o2[1] = ((dp4[B])[R])[L];
  228.  
  229.       R = r[1]; B = b[1];
  230.  
  231.       L = l[2];
  232.       o1[2] = ((dp2[B])[R])[L];
  233.       L = l[3];
  234.       o1[3] = ((dp10[B])[R])[L];
  235.       L = l2[2];
  236.       o2[2] = ((dp14[B])[R])[L];
  237.       L = l2[3];
  238.       o2[3] = ((dp6[B])[R])[L];
  239.  
  240.       R = r[2]; B = b[2];
  241.  
  242.       L = l[4];
  243.       o1[4] = ((dp0[B])[R])[L];
  244.       L = l[5];
  245.       o1[5] = ((dp8[B])[R])[L];
  246.       L = l2[4];
  247.       o2[4] = ((dp12[B])[R])[L];
  248.       L = l2[5];
  249.       o2[5] = ((dp4[B])[R])[L];
  250.  
  251.       R = r[3]; B = b[3];
  252.  
  253.       L = l[6];
  254.       o1[6] = ((dp2[B])[R])[L];
  255.       L = l[7];
  256.       o1[7] = ((dp10[B])[R])[L];
  257.       L = l2[6];
  258.       o2[6] = ((dp14[B])[R])[L];
  259.       L = l2[7];
  260.       o2[7] = ((dp6[B])[R])[L];
  261.  
  262.       l += 8;
  263.       l2 += 8;
  264.       r += 4;
  265.       b += 4;
  266.       o1 += 8;
  267.       o2 += 8;
  268.     }
  269.  
  270.     l += w; 
  271.     l2 += w;
  272.     o1 += w; 
  273.     o2 += w;
  274.  
  275.     for (j=0; j<w; j+=8) {
  276.  
  277.       R = r[0]; B = b[0];
  278.  
  279.       L = l[0];
  280.       o1[0] = ((dp3[B])[R])[L];
  281.       L = l[1];
  282.       o1[1] = ((dp11[B])[R])[L];
  283.       L = l2[0];
  284.       o2[0] = ((dp15[B])[R])[L];
  285.       L = l2[1];
  286.       o2[1] = ((dp7[B])[R])[L];
  287.  
  288.       R = r[1]; B = b[1];
  289.  
  290.       L = l[2];
  291.       o1[2] = ((dp1[B])[R])[L];
  292.       L = l[3];
  293.       o1[3] = ((dp9[B])[R])[L];
  294.       L = l2[2];
  295.       o2[2] = ((dp13[B])[R])[L];
  296.       L = l2[3];
  297.       o2[3] = ((dp5[B])[R])[L];
  298.  
  299.       R = r[2]; B = b[2];
  300.  
  301.       L = l[4];
  302.       o1[4] = ((dp3[B])[R])[L];
  303.       L = l[5];
  304.       o1[5] = ((dp11[B])[R])[L];
  305.       L = l2[4];
  306.       o2[4] = ((dp15[B])[R])[L];
  307.       L = l2[5];
  308.       o2[5] = ((dp7[B])[R])[L];
  309.  
  310.       R = r[3]; B = b[3];
  311.  
  312.       L = l[6];
  313.       o1[6] = ((dp1[B])[R])[L];
  314.       L = l[7];
  315.       o1[7] = ((dp9[B])[R])[L];
  316.       L = l2[6];
  317.       o2[6] = ((dp13[B])[R])[L];
  318.       L = l2[7];
  319.       o2[7] = ((dp5[B])[R])[L];
  320.  
  321.       l += 8;
  322.       l2 += 8;
  323.       r += 4;
  324.       b += 4;
  325.       o1 += 8;
  326.       o2 += 8;
  327.     }
  328.  
  329.     l += w; 
  330.     l2 += w;
  331.     o1 += w;
  332.     o2 += w;
  333.   }
  334. }
  335.  
  336.  
  337.   
  338.